package com.liyu.controller;

import com.liyu.config.AlternateExchangeCommon;
import com.liyu.config.PriorityExchangeCommon;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @author 李誉
 * @date 2022-07-19 21:55
 * @description
 */
@Slf4j
@RestController
@RequestMapping("send")
public class SendController {

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 添加发布确认监听
     */
    @PostConstruct
    private void init() {
        // 发布确认
        rabbitTemplate.setConfirmCallback((@Nullable CorrelationData correlationData, boolean ack, @Nullable String cause)->{
            String id = ObjectUtils.isEmpty(correlationData) ? "" : correlationData.getId();
            if (ack) {
                log.info("消息发送成功，id={}",id);
            } else {
                log.warn("消息发送失败，id={}，\n异常信息={}", id, cause);
            }
        });
        // 消息回退
        rabbitTemplate.setReturnCallback((Message message, int replyCode, String replyText, String exchange, String routingKey)-> {
            log.warn("信息被回退，消息:{}，退回原因:{}，重复编号{}", new String(message.getBody()), replyText, replyCode);
        });
    }

    /**
     * 交换机不存在
     */
    @GetMapping("{id}/{msg}")
    public void sendNoExchange(@PathVariable("id") String id, @PathVariable("msg") String msg) {
//        设置correlationData，发布确认时，我们通过这个匹配信息
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(id);
        rabbitTemplate.convertAndSend("ex.no", "rk.no", msg, message -> {
            MessageProperties messageProperties = message.getMessageProperties();
            // 设置十秒过期时间
            messageProperties.setExpiration("10000");
            return message;
        }, correlationData);
    }

    /**
     * 交换机存在，队列不存在
     */
    @GetMapping("noQueue/{id}/{msg}")
    public void sendNoQueue(@PathVariable("id") String id, @PathVariable("msg") String msg) {
//        设置correlationData，发布确认时，我们通过这个匹配信息
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(id);
        rabbitTemplate.convertAndSend("normal.exchange.hello", "rk.no", msg, message -> {
            MessageProperties messageProperties = message.getMessageProperties();
            // 设置十秒过期时间
            messageProperties.setExpiration("10000");
            return message;
        }, correlationData);
    }

    /**
     * 备份交换机测试
     */
    @GetMapping("alternate/{id}/{msg}")
    public void alternate(@PathVariable("id") String id, @PathVariable("msg") String msg) {
//        设置correlationData，发布确认时，我们通过这个匹配信息
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(id);
        rabbitTemplate.convertAndSend(AlternateExchangeCommon.NORMAL_EXCHANGE, AlternateExchangeCommon.HELLO_RK, msg, message -> message, correlationData);
    }


    /**
     * 优先级
     */
    @GetMapping("priority")
    public void priority() {
        sendPriority(1, "消息A");
        sendPriority(2, "消息B");
        sendPriority(3, "消息C");
        sendPriority(4, "消息D");
        sendPriority(5, "消息E");


    }

    private void sendPriority(int priority, String msg) {
        rabbitTemplate.convertAndSend(PriorityExchangeCommon.PRIORITY_EXCHANGE, PriorityExchangeCommon.PRIORITY_ROUTING_KEY, msg, message -> {
            MessageProperties properties = message.getMessageProperties();
            properties.setPriority(priority);
            return message;
        });
        log.info("成功发送消息{}，优先级：{}", msg, priority);
    }
}
